/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.inspur.edp.cef.generator.common;

import com.inspur.edp.caf.generator.baseInfo.TypeInfo;
import com.inspur.edp.cef.gencommon.MediateType;
import java.util.Map;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ClassInstanceCreation;
import org.eclipse.jdt.core.dom.MethodInvocation;
import org.eclipse.jdt.core.dom.ParameterizedType;
import org.eclipse.jdt.core.dom.ReturnStatement;
import org.eclipse.jdt.core.dom.Statement;
import org.eclipse.jdt.core.dom.StringLiteral;
import org.eclipse.jdt.core.dom.TypeLiteral;
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
import org.eclipse.jdt.core.dom.VariableDeclarationStatement;

public final class BuildTypeDicStatementUtil {
  // Dictionary<string,Type> dic=new Dictionary<string,Type>();
  // dic.add(key, value);
  // return dic;
  public static java.util.ArrayList<Statement> buildTypeDic(
      AST ast, java.util.HashMap<String, MediateType> mediateType) {
    String para_dic = "dic";
    java.util.ArrayList<Statement> list = new java.util.ArrayList();
    ParameterizedType parameterizedType =
        ast.newParameterizedType(ast.newSimpleType(ast.newSimpleName("HashMap")));
    parameterizedType.typeArguments().add(new TypeInfo(String.class).getType(ast));
    parameterizedType.typeArguments().add(new TypeInfo(Class.class).getType(ast));

    ClassInstanceCreation classInstanceCreation = ast.newClassInstanceCreation();
    classInstanceCreation.setType(parameterizedType);
//    classInstanceCreation.typeArguments().add(ast.newSimpleType(ast.newSimpleName("String")));
//    classInstanceCreation.typeArguments().add(new TypeInfo(Object.class).getType(ast));
    VariableDeclarationFragment variableDeclarationFragment = ast.newVariableDeclarationFragment();
    variableDeclarationFragment.setInitializer(classInstanceCreation);
    variableDeclarationFragment.setName(ast.newSimpleName(para_dic));

    VariableDeclarationStatement variableDeclarationStatement = ast
        .newVariableDeclarationStatement(variableDeclarationFragment);

    ParameterizedType statementParameterizedType =
        ast.newParameterizedType(ast.newSimpleType(ast.newSimpleName("HashMap")));
    statementParameterizedType.typeArguments().add(new TypeInfo(String.class).getType(ast));
    statementParameterizedType.typeArguments().add(new TypeInfo(Class.class).getType(ast));

    variableDeclarationStatement.setType(statementParameterizedType);
    list.add(variableDeclarationStatement);

    // dic.add(key, value);
    if (mediateType != null && mediateType.size() > 0) {
      for (Map.Entry<String, MediateType> item : mediateType.entrySet()) {
        list.add(buildAddDicItem(ast, para_dic, item.getKey(), item.getValue().getClassName()));
      }
    }
    // return dic;
    list.add(buildReturnStatement(ast, para_dic));
    return list;
  }

  /**
   * dic.add(key,value);
   *
   * @param dicPropName 字典属性名
   * @param key 键
   * @param typeClassName 值,仅限当前命名空间类
   * @return
   */
  private static Statement buildAddDicItem(
      AST ast, String dicPropName, String key, String typeClassName) {

    MethodInvocation putMethodInvocation = ast.newMethodInvocation();
    putMethodInvocation.setExpression(ast.newSimpleName(dicPropName));
    putMethodInvocation.setName(ast.newSimpleName("put"));
    StringLiteral keyLiteral = ast.newStringLiteral();
    keyLiteral.setLiteralValue(key);
    putMethodInvocation.arguments().add(keyLiteral);
    TypeLiteral valueLiteral = ast.newTypeLiteral();
    valueLiteral.setType(ast.newSimpleType(ast.newSimpleName(typeClassName)));
    putMethodInvocation.arguments().add(valueLiteral);

    return ast.newExpressionStatement(putMethodInvocation);
  }

  /**
   * return dic;
   *
   * @return
   */
  private static ReturnStatement buildReturnStatement(AST ast, String dicPropName) {
    ReturnStatement returnStatement = ast.newReturnStatement();
    returnStatement.setExpression(ast.newSimpleName(dicPropName));
    return returnStatement;
  }
}
